﻿package ua.mihaylenko.app.data 
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.ProgressEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.getQualifiedClassName;
	import flash.utils.getQualifiedSuperclassName
	import flash.utils.unescapeMultiByte;
	import ua.mihaylenko.app.controller.APPStage;
	import ua.mihaylenko.app.data.assets.AssetManager;
	import ua.mihaylenko.app.data.assets.FontsManager;
	import ua.mihaylenko.app.data.str.DataStrings;
	import ua.mihaylenko.app.interfaces.IUIData;
	import ua.mihaylenko.app.ui.preloader.UIPreloader;
	import ua.mihaylenko.app.ui.window.UIWindow;
	import ua.mihaylenko.app.ui.window.WindowEvent;
	/**
	 * ...
	 * @author Mihaylenko A.L.
	 */
	public class AppData extends EventDispatcher
	{
		static private const APP_FILE:String = 'app-config.xml';
		static private var $instance:AppData;
		private var _xData:XML;
		private var _bLocal:Boolean;
		private var _lConfig:URLLoader;
		private var _cPreloader:UIPreloader;
		private var _dStrings:DataStrings;
		private var _cFontsManager:FontsManager;
		private var _cAssetsManager:AssetManager;
		public function AppData()
		{
			
		}
		
		static public function get instance():AppData {
			if (!$instance)$instance = new AppData();
			return $instance;
		}
		
		public function innit():void {
			
			_cPreloader = new UIPreloader();
			_cPreloader.innit([UIWindow.LEFT_RIGHT, 40, 20, 20, 'Loading']);
			_cPreloader.addEventListener(WindowEvent.WINDOW_SHOW_COMPLETE, onStartLoadConfig);
			_cPreloader.show();			
		}
		
		private function onStartLoadConfig(e:WindowEvent=null):void 
		{
			_cPreloader.removeEventListener(WindowEvent.WINDOW_SHOW_COMPLETE, onStartLoadConfig);
			_lConfig = new URLLoader();
			_lConfig.dataFormat = URLLoaderDataFormat.TEXT;
			_lConfig.addEventListener(Event.COMPLETE, onDataLoaded);
			_lConfig.addEventListener(ProgressEvent.PROGRESS, showProgressLoadConfig);
			try {
				_lConfig.load(new URLRequest(APPStage.APP_CONTENT_URL + APP_FILE));
			}catch (e:Error) { 
				_lConfig.removeEventListener(Event.COMPLETE, onDataLoaded);
				_lConfig.removeEventListener(ProgressEvent.PROGRESS, showProgressLoadConfig);
				_lConfig = null;
				dispatchEvent(new Event(Event.COMPLETE));
				onError();
			}
		}
		
		private function showProgressLoadConfig(e:ProgressEvent):void 
		{
			if (_cPreloader)_cPreloader.onProgress(e);
		}
		public function onError(e:Event = null):void {
			APPStage.error('Error load config game file');
		}
		private function onDataLoaded(e:Event):void 
		{
			_lConfig.removeEventListener(Event.COMPLETE, onDataLoaded);
			_lConfig.removeEventListener(ProgressEvent.PROGRESS, showProgressLoadConfig);
			_xData = new XML(_lConfig.data);
			_bLocal = Boolean(Number(_xData.setting.@local));
			_dStrings = getData(DataStrings) as DataStrings;
			_cFontsManager = new FontsManager();
			_cFontsManager.addEventListener(Event.COMPLETE, onFontsComplete);
			_cFontsManager.innit(_cPreloader);
			//_cPreloader.addEventListener(WindowEvent.WONDOW_CLOSE, onPreloaderDispose);
			//_cPreloader.hide();
		}
		
		private function onFontsComplete(e:Event):void 
		{
			_cFontsManager.removeEventListener(Event.COMPLETE, onFontsComplete);
			_cAssetsManager = new AssetManager();
			_cAssetsManager.innit();
		}
		
		private function onPreloaderDispose(e:WindowEvent):void 
		{
			_cPreloader.removeEventListener(WindowEvent.WONDOW_CLOSE, onPreloaderDispose);
			_cPreloader = null;
			dispatchEvent(new Event(Event.COMPLETE));			
		}
		public function getData(cDataClass:Class):IUIData {
			if (! cDataClass is IUIData) return null;
			var cDataReturn:IUIData = new cDataClass();
			
			if (cDataReturn) {
				var sName:String = getQualifiedClassName(cDataReturn);
				for each(var $xNode:XML in _xData.elements()) {
					if ($xNode.@className == sName) {
						cDataReturn.innitData($xNode);
						return cDataReturn;
					}
				}
			}
			return cDataReturn;
		}
		public function get dataStrings():DataStrings { return _dStrings; }
		public function get isLocal():Boolean { return _bLocal; }
	}
	

}